package com.sky.skyopsserver.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sky.skyopsserver.aspect.ApiOperationLog;
import com.sky.skyopsserver.service.NotificationService;
import com.sky.skyopsserver.utils.PageResponse;
import com.sky.skyopsserver.utils.Response;
import com.sky.skyopsserver.vos.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 通知信息控制器
 * 
 * @author Administrator
 * @since 2025-01-17
 */
@Slf4j
@RestController
@RequestMapping("/api/notification")
@RequiredArgsConstructor
@Validated
@Tag(name = "通知管理", description = "通知信息的增删改查操作")
public class NotificationController {

    private final NotificationService notificationService;

    /**
     * 添加通知
     * 
     * @param reqVO 添加通知请求VO
     * @return 通知ID
     */
    @PostMapping("/add")
    @Operation(summary = "添加通知", description = "新增一个通知配置")
    @ApiOperationLog(description = "添加通知")
    public Response<Long> addNotification(@Valid @RequestBody NotificationAddReqVO reqVO) {
        Long notificationId = notificationService.addNotification(reqVO);
        return Response.success(notificationId);
    }

    /**
     * 更新通知信息
     * 
     * @param reqVO 更新通知请求VO
     * @return 操作结果
     */
    @PutMapping("/update")
    @Operation(summary = "更新通知信息", description = "修改通知的配置信息")
    @ApiOperationLog(description = "更新通知信息")
    public Response<Boolean> updateNotification(@Valid @RequestBody NotificationUpdateReqVO reqVO) {
        Boolean result = notificationService.updateNotification(reqVO);
        return Response.success(result);
    }

    /**
     * 删除通知
     * 
     * @param id 通知ID
     * @return 操作结果
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除通知", description = "根据ID删除指定通知")
    @ApiOperationLog(description = "删除通知")
    public Response<Boolean> deleteNotification(
            @Parameter(description = "通知ID", required = true)
            @PathVariable("id") @NotNull(message = "通知ID不能为空") @Positive(message = "通知ID必须为正数") Long id) {
        Boolean result = notificationService.deleteNotification(id);
        return Response.success(result);
    }

    /**
     * 批量删除通知
     * 
     * @param ids 通知ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量删除通知", description = "根据ID列表批量删除通知")
    @ApiOperationLog(description = "批量删除通知")
    public Response<Boolean> batchDeleteNotification(
            @Parameter(description = "通知ID列表", required = true)
            @RequestBody @NotEmpty(message = "通知ID列表不能为空") List<@Positive(message = "通知ID必须为正数") Long> ids) {
        Boolean result = notificationService.batchDeleteNotification(ids);
        return Response.success(result);
    }

    /**
     * 根据ID查询通知详情
     * 
     * @param id 通知ID
     * @return 通知详情
     */
    @GetMapping("/detail/{id}")
    @Operation(summary = "查询通知详情", description = "根据ID获取通知的详细信息")
    @ApiOperationLog(description = "查询通知详情")
    public Response<NotificationRspVO> getNotificationById(
            @Parameter(description = "通知ID", required = true)
            @PathVariable("id") @NotNull(message = "通知ID不能为空") @Positive(message = "通知ID必须为正数") Long id) {
        NotificationRspVO result = notificationService.getNotificationById(id);
        return Response.success(result);
    }

    /**
     * 根据名称查询通知
     * 
     * @param name 通知名称
     * @return 通知信息
     */
    @GetMapping("/detail/name/{name}")
    @Operation(summary = "根据名称查询通知", description = "根据通知名称获取通知信息")
    @ApiOperationLog(description = "根据名称查询通知")
    public Response<NotificationRspVO> getNotificationByName(
            @Parameter(description = "通知名称", required = true)
            @PathVariable("name") @NotBlank(message = "通知名称不能为空") String name) {
        NotificationRspVO result = notificationService.getNotificationByName(name);
        return Response.success(result);
    }

    /**
     * 分页查询通知列表
     * 
     * @param reqVO 分页查询请求VO
     * @return 分页结果
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询通知列表", description = "根据条件分页查询通知信息")
    @ApiOperationLog(description = "分页查询通知列表")
    public PageResponse<NotificationRspVO> getNotificationPage(@Valid @RequestBody NotificationPageReqVO reqVO) {
        IPage<NotificationRspVO> page = notificationService.getNotificationPage(reqVO);
        return PageResponse.success(page, page.getRecords());
    }

    /**
     * 查询所有通知选项（用于下拉选择）
     * 
     * @return 通知选项列表
     */
    @GetMapping("/options")
    @Operation(summary = "查询通知选项", description = "获取所有通知的选项列表，用于下拉选择")
    @ApiOperationLog(description = "查询通知选项")
    public Response<List<NotificationOptionRspVO>> getAllNotificationOptions() {
        List<NotificationOptionRspVO> result = notificationService.getAllNotificationOptions();
        return Response.success(result);
    }

    /**
     * 根据通知方式查询通知选项
     * 
     * @param type 通知方式
     * @return 通知选项列表
     */
    @GetMapping("/options/type/{type}")
    @Operation(summary = "按方式查询通知选项", description = "根据通知方式获取通知选项列表")
    @ApiOperationLog(description = "按方式查询通知选项")
    public Response<List<NotificationOptionRspVO>> getNotificationOptionsByType(
            @Parameter(description = "通知方式", required = true)
            @PathVariable("type") @NotBlank(message = "通知方式不能为空") String type) {
        List<NotificationOptionRspVO> result = notificationService.getNotificationOptionsByType(type);
        return Response.success(result);
    }

    /**
     * 获取通知统计信息
     * 
     * @return 通知统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取通知统计信息", description = "获取通知的各项统计数据")
    @ApiOperationLog(description = "获取通知统计信息")
    public Response<NotificationStatisticsRspVO> getNotificationStatistics() {
        NotificationStatisticsRspVO result = notificationService.getNotificationStatistics();
        return Response.success(result);
    }

    /**
     * 检查通知名称是否已存在
     * 
     * @param name 通知名称
     * @param excludeId 排除的通知ID（可选）
     * @return 是否存在
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查通知名称", description = "检查通知名称是否已存在")
    @ApiOperationLog(description = "检查通知名称")
    public Response<Boolean> checkNotificationNameExists(
            @Parameter(description = "通知名称", required = true)
            @RequestParam("name") @NotBlank(message = "通知名称不能为空") String name,
            @Parameter(description = "排除的通知ID")
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        Boolean result = notificationService.checkNotificationNameExists(name, excludeId);
        return Response.success(result);
    }

    /**
     * 根据名称模糊查询通知
     * 
     * @param name 通知名称关键字
     * @return 通知列表
     */
    @GetMapping("/search/name")
    @Operation(summary = "按名称搜索通知", description = "根据通知名称关键字模糊查询通知")
    @ApiOperationLog(description = "按名称搜索通知")
    public Response<List<NotificationRspVO>> searchNotificationByName(
            @Parameter(description = "通知名称关键字", required = true)
            @RequestParam("name") @NotBlank(message = "通知名称关键字不能为空") String name) {
        List<NotificationRspVO> result = notificationService.searchNotificationByName(name);
        return Response.success(result);
    }

    /**
     * 根据通知方式查询通知
     * 
     * @param type 通知方式
     * @return 通知列表
     */
    @GetMapping("/list/type/{type}")
    @Operation(summary = "按方式查询通知", description = "根据通知方式查询通知列表")
    @ApiOperationLog(description = "按方式查询通知")
    public Response<List<NotificationRspVO>> getNotificationsByType(
            @Parameter(description = "通知方式", required = true)
            @PathVariable("type") @NotBlank(message = "通知方式不能为空") String type) {
        List<NotificationRspVO> result = notificationService.getNotificationsByType(type);
        return Response.success(result);
    }

    /**
     * 验证通知方式是否有效
     * 
     * @param type 通知方式
     * @return 是否有效
     */
    @GetMapping("/validate-type")
    @Operation(summary = "验证通知方式", description = "验证通知方式是否有效")
    @ApiOperationLog(description = "验证通知方式")
    public Response<Boolean> validateNotificationType(
            @Parameter(description = "通知方式", required = true)
            @RequestParam("type") @NotBlank(message = "通知方式不能为空") String type) {
        Boolean result = notificationService.validateNotificationType(type);
        return Response.success(result);
    }

    /**
     * 验证邮箱格式是否有效
     * 
     * @param email 邮箱地址
     * @return 是否有效
     */
    @GetMapping("/validate-email")
    @Operation(summary = "验证邮箱格式", description = "验证邮箱地址格式是否正确")
    @ApiOperationLog(description = "验证邮箱格式")
    public Response<Boolean> validateEmail(
            @Parameter(description = "邮箱地址", required = true)
            @RequestParam("email") @NotBlank(message = "邮箱地址不能为空") String email) {
        Boolean result = notificationService.validateEmail(email);
        return Response.success(result);
    }

    /**
     * 验证Webhook地址是否有效
     * 
     * @param webhookUrl Webhook地址
     * @return 是否有效
     */
    @GetMapping("/validate-webhook")
    @Operation(summary = "验证Webhook地址", description = "验证Webhook地址格式是否正确")
    @ApiOperationLog(description = "验证Webhook地址")
    public Response<Boolean> validateWebhookUrl(
            @Parameter(description = "Webhook地址", required = true)
            @RequestParam("webhookUrl") @NotBlank(message = "Webhook地址不能为空") String webhookUrl) {
        Boolean result = notificationService.validateWebhookUrl(webhookUrl);
        return Response.success(result);
    }

    /**
     * 获取所有通知方式列表
     * 
     * @return 通知方式列表
     */
    @GetMapping("/types")
    @Operation(summary = "获取通知方式", description = "获取所有支持的通知方式列表")
    @ApiOperationLog(description = "获取通知方式列表")
    public Response<List<Map<String, Object>>> getAllNotificationTypes() {
        List<Map<String, Object>> result = notificationService.getAllNotificationTypes();
        return Response.success(result);
    }

    /**
     * 获取所有通知名称列表
     * 
     * @return 通知名称列表
     */
    @GetMapping("/names")
    @Operation(summary = "获取通知名称列表", description = "获取所有通知的名称列表")
    @ApiOperationLog(description = "获取通知名称列表")
    public Response<List<String>> getAllNotificationNames() {
        List<String> result = notificationService.getAllNotificationNames();
        return Response.success(result);
    }

    /**
     * 测试通知配置
     * 
     * @param id 通知ID
     * @param testMessage 测试消息
     * @return 测试结果
     */
    @PostMapping("/test/{id}")
    @Operation(summary = "测试通知配置", description = "测试指定通知的配置是否正确")
    @ApiOperationLog(description = "测试通知配置")
    public Response<Boolean> testNotification(
            @Parameter(description = "通知ID", required = true)
            @PathVariable("id") @NotNull(message = "通知ID不能为空") @Positive(message = "通知ID必须为正数") Long id,
            @Parameter(description = "测试消息", required = true)
            @RequestParam("testMessage") @NotBlank(message = "测试消息不能为空") String testMessage) {
        Boolean result = notificationService.testNotification(id, testMessage);
        return Response.success(result);
    }

    /**
     * 发送通知
     * 
     * @param id 通知ID
     * @param title 消息标题
     * @param content 消息内容
     * @return 发送结果
     */
    @PostMapping("/send/{id}")
    @Operation(summary = "发送通知", description = "使用指定通知配置发送消息")
    @ApiOperationLog(description = "发送通知")
    public Response<Boolean> sendNotification(
            @Parameter(description = "通知ID", required = true)
            @PathVariable("id") @NotNull(message = "通知ID不能为空") @Positive(message = "通知ID必须为正数") Long id,
            @Parameter(description = "消息标题", required = true)
            @RequestParam("title") @NotBlank(message = "消息标题不能为空") String title,
            @Parameter(description = "消息内容", required = true)
            @RequestParam("content") @NotBlank(message = "消息内容不能为空") String content) {
        Boolean result = notificationService.sendNotification(id, title, content);
        return Response.success(result);
    }

    /**
     * 清理过期通知
     * 
     * @param days 保留天数
     * @return 清理数量
     */
    @DeleteMapping("/clean-expired")
    @Operation(summary = "清理过期通知", description = "清理指定天数之前的过期通知")
    @ApiOperationLog(description = "清理过期通知")
    public Response<Long> cleanExpiredNotifications(
            @Parameter(description = "保留天数", required = true)
            @RequestParam("days") @NotNull(message = "保留天数不能为空") @Positive(message = "保留天数必须为正数") Integer days) {
        Long result = notificationService.cleanExpiredNotifications(days);
        return Response.success(result);
    }
}